/*@@

	Copyright (c) 2010 BlueSky LTD. All rights reserved. 

	Created_datetime : 	2010-6-21

	File Name :	base_inifile.cpp

	Author : liusiliang (siliangliu@msn.com)

	Description : 

@@*/


#include <cstdio>
#include <cstring>

#include "base/base_inifile.h"
#include "base/base_str.h"
#include "base/base_packfile.h"



namespace BLK
{
	//////////////////////////////////////////////////////////////////////////
	//
	//		Global variables and Macro and Structure Definitions
	//
	//////////////////////////////////////////////////////////////////////////

	/*
	 *	功能:	购造函数
	 */
	IniFile::IniFile(void)
	{
		::memset(&m_Header, 0, sizeof(SECNODE));
	}

	/*
	 *	功能:	析造函数
	 */
	IniFile::~IniFile(void)
	{
		Clear();
	}

	/*
	 *	功能:	加载一个INI文件
	 *	参数:	FileName	文件名
	 *	返回:	true		成功
	 *			false		失败
	 */
	bool IniFile::Load(const char* pFileName)
	{
		unsigned long		dwSize;
		void*				pBuffer;

		// check file name
		if(pFileName[0] == 0)
			return false;

		if(m_Header.pNextNode)
			Clear();

		// Modified by Lulu
		PackFile			File;
		if(!File.Open((char*)pFileName))
		{
			return false;
		}
	
		dwSize = File.Size();
		pBuffer = m_MemStack.Push(dwSize + 4);
		File.Read(pBuffer, dwSize);

// 		std::ifstream inFile;
// 		inFile.open(pFileName);
// 		if(!inFile.good())
// 		{
// 			return false;
// 		}
// 
// 		inFile.seekg(0, std::ios::end);
// 		dwSize = inFile.tellg();
// 		inFile.seekg(0, std::ios::beg);
// 		pBuffer = m_MemStack.Push(dwSize + 4);
// 		inFile.read((char*)pBuffer, dwSize);

		CreateIniLink(pBuffer, dwSize);

		return true;
	}

	/*
	 *	功能:	保存当前的INI文件
	 *	参数:	FileName	保存文件名
	 *	返回:	true		成功
	 *			false		失败
	 */
	bool IniFile::Save(const char* pFileName)
	{
		char*		DataBuf;
		char*		pBuffer;
		unsigned long		dwLen;
		
		if(pFileName[0] == 0)
			return false;
		
		dwLen = m_MemStack.GetStackSize();

		DataBuf = (char*)m_MemStack.Push(dwLen);
		pBuffer = DataBuf;
		
		SECNODE* SecNode = m_Header.pNextNode;
		KEYNODE* KeyNode = NULL;
		
		// write ini file to memory buffer
		while(SecNode != NULL)
		{
			dwLen = ::sprintf(pBuffer, "%s\r\n", SecNode->pSection);
			pBuffer += dwLen;
			KeyNode = SecNode->pKeyNode.pNextNode;
			while(KeyNode != NULL)
			{
				dwLen = ::sprintf(pBuffer, 
					"%s%c%s\r\n", 
					KeyNode->pKey, 
					BLK_EQUAL, 
					KeyNode->pValue);

				pBuffer += dwLen;
				KeyNode = KeyNode->pNextNode;
			}
			SecNode = SecNode->pNextNode;
			dwLen = ::sprintf(pBuffer, "\r\n");
			pBuffer += dwLen;
		}

		// get buffer len
		dwLen = (unsigned long)(pBuffer - DataBuf);

		// create ini file
		std::ofstream	saveFile;
		saveFile.open(pFileName);
		saveFile << DataBuf;
		saveFile.close();

// 		FILE saveFile;
// 		if(BLK_NOERROR != saveFile.Create(
// 			(char*)pFileName, 
// 			File::FILEMODE_WRITE, 
// 			true))
// 			return false;
// 
// 		// write ini file
// 		unsigned int uWriteLen;
// 		saveFile.Write(DataBuf, dwLen, uWriteLen);

		return true;
	}

	/*
	 *	功能:	清除INI文件的内容
	 */
	void IniFile::Clear(void)
	{
		ReleaseIniLink();
	}

	/*
	 *	功能:	读取INI文件的一行
	 *	参数:	Buffer	缓存
	 *			Szie	长度
	 *	返回:	true		成功
	 *			false		失败
	 */
	bool IniFile::ReadLine(
		char* pBuffer, 
		long lSize)
	{
		if(m_Offset >= lSize)
		{
			return false;
		}

		int nCount = 0;
		while(pBuffer[m_Offset] != 0x0D && 
			pBuffer[m_Offset] != 0x0A)
		{
			m_Offset++; 
			nCount++;
			if(m_Offset >= lSize)
				break;
		}
			
		if(nCount == 0)
		{
			if(pBuffer[m_Offset] == 0x0D && 
				pBuffer[m_Offset + 1] == 0x0A)
			{
				m_Offset += 2;
			}
			else
			{
				m_Offset += 1;	//linux
			}
			
			return false;
		}
		
		if(pBuffer[m_Offset] == 0x0D && 
			pBuffer[m_Offset + 1] == 0x0A)
		{
			m_Offset += 2;
			pBuffer[m_Offset-2] = 0;
		}
		else
		{
			m_Offset += 1;	//linux
			pBuffer[m_Offset-1] = 0;
		}

		return true;
	}

	/*
	 *	功能:	创建Ini链表
	 *	参数:	pBuffer		缓存
	 *			nBufLen		长度
	 */
	void IniFile::CreateIniLink(
		void* pBuffer, 
		long nBufLen)
	{
		char* lpBuffer = (char*)pBuffer;
		char* lpString = NULL;
		char* lpValue  = NULL;
		char  szSection[32] = "[MAIN]";

		m_Offset = 0;
		while(m_Offset < nBufLen)
		{
			lpString = &lpBuffer[m_Offset];
			if(!ReadLine(lpBuffer, nBufLen))
			{
				continue;
			}

			if(*lpString == BLK_SEMICOLON)
			{
				continue;
			}
			
			if(*lpString == BLK_POUND)
			{
				continue;
			}

			if(*lpString == BLK_LEFT_BRACKET)
			{
				::strncpy(szSection, lpString, sizeof(szSection));

				continue;
			}

			lpValue = SplitKeyValue(lpString);
			SetKeyValue(szSection, lpString, lpValue);
		}
	}

	/*
	 *	功能:	释放Ini链表
	 */
	void IniFile::ReleaseIniLink(void)
	{
		SECNODE* pThisSec = &m_Header;
		SECNODE* pNextSec = pThisSec->pNextNode;
		KEYNODE* pThisKey = NULL;
		KEYNODE* pNextKey = NULL;

		while(pNextSec != NULL)
		{
			pThisSec = pNextSec->pNextNode;
			pThisKey = &pNextSec->pKeyNode;
			pNextKey = pThisKey->pNextNode;

			while(pNextKey != NULL)
			{
				pThisKey = pNextKey->pNextNode;
				m_MemStack.Free(pNextKey->pKey);
				m_MemStack.Free(pNextKey->pValue);
				m_MemStack.Free(pNextKey);
				pNextKey = pThisKey;
			}

			m_MemStack.Free(pNextSec->pSection);
			m_MemStack.Free(pNextSec);
			pNextSec = pThisSec;
		}
		m_Header.pNextNode = NULL;

		m_MemStack.FreeAllChunks();
	}

	/*
	 *	功能:	分割Key和Value
	 *	参数:	pString		Key=Value
	 *	返回:	指向Value
	 */
	char* IniFile::SplitKeyValue(char* pString)
	{
		char* pValue = pString;
		while(*pValue)
		{
			if(*pValue == BLK_EQUAL)
				break;
			pValue++;
		}

		*pValue = 0;
		return pValue + 1;
	}

	/*
	 *	功能:	字符串转成32 bits ID
	 *	参数:	pString		字符串
	 *	返回:	32 bits ID
	 */
	unsigned long IniFile::String2Id(const char* pString)
	{
		unsigned long Id = 0;
		for(int i = 0; pString[i]; i++)
		{
			Id = (Id + (i + 1) * pString[i]) % 0x8000000b * 0xffffffef;
		}
		return Id ^ 0x12345678;
	}

	/*
	 *	功能:	Section是否存在
	 *	参数:	pSection	节的名字
	 *	返回:	true 存在
	 *			false 不存在
	 */
	bool IniFile::IsSectionExist(const char* pSection)
	{
		// setup section name
		char szSection[32] = "[";
		if(pSection[0] != BLK_LEFT_BRACKET)
		{
			::strcat(szSection, pSection);
			::strcat(szSection, "]");
		}
		else
		{
			::strcpy(szSection, pSection);
		}
		
		// search for the matched section
		SECNODE* pSecNode = m_Header.pNextNode;
		unsigned long dwID = String2Id(szSection);
		
		while(pSecNode != NULL)
		{
			if(dwID == pSecNode->dwID)
				return true;

			pSecNode = pSecNode->pNextNode;
		}
		
		return false;
	}

	/*
	 *	功能:	清除一个Section的内容
	 *	参数:	pSection	节的名字
	 */
	void IniFile::EraseSection(const char* pSection)
	{
		// setup section name
		char szSection[32] = "[";
		if(pSection[0] != BLK_LEFT_BRACKET)
		{
			::strcat(szSection, pSection);
			::strcat(szSection, "]");
		}
		else
		{
			::strcpy(szSection, pSection);
		}

		// search for the matched section
		SECNODE* pSecNode = m_Header.pNextNode;
		unsigned long dwID = String2Id(szSection);
		while(pSecNode != NULL)
		{
			if(dwID == pSecNode->dwID)
			{
				break;
			}
			pSecNode = pSecNode->pNextNode;
		}

		// if no such section found
		if(pSecNode == NULL)
			return;

		// erase all key in the section
		KEYNODE* pThisKey = &pSecNode->pKeyNode;
		KEYNODE* pNextKey = pThisKey->pNextNode;
		while(pNextKey != NULL)
		{
			pThisKey = pNextKey->pNextNode;
			m_MemStack.Free(pNextKey->pKey);
			m_MemStack.Free(pNextKey->pValue);
			m_MemStack.Free(pNextKey);
			pNextKey = pThisKey;
		}
		pSecNode->pKeyNode.pNextNode = NULL;
	}

	/*
	 *	功能:	清除Section的下一个Key的内容
	 *	参数:	pSection	节的名字
	 */
	void IniFile::EraseKey(
		const char* lpSection, 
		const char* lpKey)
	{
		// setup section name
		char szSection[32] = "[";
		if(lpSection[0] != BLK_LEFT_BRACKET)
		{
			::strcat(szSection, lpSection);
			::strcat(szSection, "]");
		}
		else
		{
			::strcpy(szSection, lpSection);
		}

		// search for the matched section
		SECNODE* pSecNode = m_Header.pNextNode;
		unsigned long dwID = String2Id(szSection);
		while(pSecNode != NULL)
		{
			if(dwID == pSecNode->dwID)
			{
				break;
			}
			pSecNode = pSecNode->pNextNode;
		}

		// if no such section found
		if(pSecNode == NULL)
			return;

		// erase all key in the section
		KEYNODE* pThisKey = &pSecNode->pKeyNode;
		KEYNODE* pNextKey = pThisKey->pNextNode;
		dwID = String2Id(lpKey);
		while(pNextKey != NULL)
		{
			if(pNextKey->dwID == dwID)
			{
				pThisKey->pNextNode = pNextKey->pNextNode;
				m_MemStack.Free(pNextKey->pKey);
				m_MemStack.Free(pNextKey->pValue);
				m_MemStack.Free(pNextKey);
				return;
			}
			pThisKey = pNextKey;
			pNextKey = pNextKey->pNextNode;
		}

	}

	/*
	 *	功能:	设置Key的Value
	 *	参数:	pSection	节名
	 *			pKey		建名
	 *			pValue		建值
	 *	返回:	true－成功 false－失败
	 */
	bool IniFile::SetKeyValue(
		const char*	pSection,
		const char*	pKey,
		const char*	pValue)
	{
		if(0 == pSection[0] ||
			0 == pKey[0] || 
			!pValue)
			return false;

		int		nLen;
		unsigned long	dwID;

		// setup section name
		char szSection[32] = "[";
		if(pSection[0] != BLK_LEFT_BRACKET)
		{
			::strcat(szSection, pSection);
			::strcat(szSection, "]");
		}
		else
		{
			::strcpy(szSection, pSection);
		}

		// search for the matched section
		SECNODE* pThisSecNode = &m_Header;
		SECNODE* pNextSecNode = pThisSecNode->pNextNode;
		dwID = String2Id(szSection);
		while(pNextSecNode != NULL)
		{
			if (dwID == pNextSecNode->dwID)
			{
				break;
			}
			pThisSecNode = pNextSecNode;
			pNextSecNode = pThisSecNode->pNextNode;
		}

		// if no such section found create a new section
		if(pNextSecNode == NULL)
		{
			nLen = ::strlen(szSection) + 1;
			pNextSecNode = (SECNODE*)m_MemStack.Push(sizeof(SECNODE));
			pNextSecNode->pSection = (char*)m_MemStack.Push(nLen);
			::memcpy(pNextSecNode->pSection, szSection, nLen);
			pNextSecNode->dwID = dwID;
			pNextSecNode->pKeyNode.pNextNode = NULL;
			pNextSecNode->pNextNode = NULL;
			pThisSecNode->pNextNode = pNextSecNode;
		}

		// search for the same key
		KEYNODE* pThisKeyNode = &pNextSecNode->pKeyNode;
		KEYNODE* pNextKeyNode = pThisKeyNode->pNextNode;
		dwID = String2Id(pKey);
		while(pNextKeyNode != NULL)
		{
			if(dwID == pNextKeyNode->dwID)
			{
				break;
			}
			pThisKeyNode = pNextKeyNode;
			pNextKeyNode = pThisKeyNode->pNextNode;
		}

		// if no such key found create a new key
		if(pNextKeyNode == NULL)
		{
			pNextKeyNode = (KEYNODE*)m_MemStack.Push(sizeof(KEYNODE));

			nLen = ::strlen(pKey) + 1;
			pNextKeyNode->pKey = (char*)m_MemStack.Push(nLen);
			::memcpy(pNextKeyNode->pKey, (void*)pKey, nLen);

			nLen = ::strlen(pValue) + 1;
			pNextKeyNode->pValue = (char*)m_MemStack.Push(nLen);
			::memcpy(pNextKeyNode->pValue, (void*)pValue, nLen);

			pNextKeyNode->dwID = dwID;
			pNextKeyNode->pNextNode = NULL;
			pThisKeyNode->pNextNode = pNextKeyNode;
		}
		// replace the old value with new
		else
		{
			m_MemStack.Free(pNextKeyNode->pValue);
			nLen = ::strlen(pValue) + 1;
			pNextKeyNode->pValue = (char*)m_MemStack.Push(nLen);
			::memcpy(pNextKeyNode->pValue, (void*)pValue, nLen);
		}
		return true;
	}

	/*
	 *	功能:	取得Key的Value
	 *	参数:	pSection	节名
	 *			pKey		建名
	 *			pValue		建值
	 *	返回:	true－成功 false－失败
	 */
	bool IniFile::GetKeyValue(
		const char*		pSection,
		const char*		pKey,
		char*			pValue,
		unsigned long	dwSize)
	{
		unsigned long	dwID;

		// setup section name
		char szSection[32] = "[";
		if(pSection[0] != BLK_LEFT_BRACKET)
		{
			::strcat(szSection, pSection);
			::strcat(szSection, "]");
		}
		else
		{
			::strcpy(szSection, pSection);
		}

		// search for the matched section
		SECNODE* pSecNode = m_Header.pNextNode;
		dwID = String2Id(szSection);
		while(pSecNode != NULL)
		{
			if(dwID == pSecNode->dwID)
			{
				break;
			}
			pSecNode = pSecNode->pNextNode;
		}

		// if no such section founded
		if(pSecNode == NULL)
		{
			return false;
		}

		// search for the same key
		KEYNODE* pKeyNode = pSecNode->pKeyNode.pNextNode;
		dwID = String2Id(pKey);
		while(pKeyNode != NULL)
		{
			if(dwID == pKeyNode->dwID)
			{
				break;
			}
			pKeyNode = pKeyNode->pNextNode;
		}

		// if no such key found
		if(pKeyNode == NULL)
			return false;

		// copy the value of the key
		::strncpy(pValue, pKeyNode->pValue, dwSize);

		return true;
	}

	/*
	 *	功能:	读取一个字符串
	 *	参数:	lpSection		节名
	 *			lpKeyName		建名
	 *			lpDefault		缺省值
	 *			lpRString		返回值
	 *			dwSize			返回字符串的最大长度
	 *	返回:	是否读取成功
	 */
	bool IniFile::GetString(
		const char*	lpSection,
		const char*	lpKeyName,
		const char*	lpDefault,
		char*		lpRString,
		unsigned long	dwSize)
	{
		if(GetKeyValue(lpSection, lpKeyName, lpRString, dwSize))
			return true;

		::strncpy(lpRString, lpDefault, dwSize);

		return false;
	}

	/*
	 *	功能:	读取一个整数
	 *	参数:	lpSection		节名
	 *			lpKeyName		建名
	 *			nDefault		缺省值
	 *			pnValue			返回值
	 *	返回:	是否读取成功
	 */
	bool IniFile::GetInteger(
		const char* lpSection,
		const char* lpKeyName,
		int nDefault,
		int* pnValue)
	{
		char Buffer[32];
		if(GetKeyValue(lpSection, lpKeyName, Buffer, sizeof(Buffer)))
		{
			*pnValue = ::atoi(Buffer);
			return true;
		}
		else
		{
			*pnValue = nDefault;
			return false;
		}
	}

	/*
	 *	功能:	读取2个整数，整数之间用逗号分割。
	 *	参数:	lpSection		节名
	 *			lpKeyName		建名
	 *			pnValue1		返回值1
	 *			pnValue2		返回值2
	 *	返回:	是否读取成功
	 */
	bool IniFile::GetInteger2(
		const char* lpSection,
		const char* lpKeyName,
		int* pnValue1,
		int* pnValue2	)
	{
		char  Buffer[32];
		char* pchar = Buffer;
		if(GetKeyValue(lpSection, lpKeyName, Buffer, sizeof(Buffer)))
		{
			while(*pchar)
			{
				if(',' == *pchar)
				{
					*pchar++ = 0;
					break;
				}
				pchar++;
			}

			*pnValue1 = ::atoi(Buffer);
			*pnValue2 = ::atoi(pchar);

			return true;
		}

		return false;
	}

	/*
	 *	功能:	读取1个浮点数
	 *	参数:	lpSection		节名
	 *			lpKeyName		建名
	 *			fDefault		缺省值
	 *			pfValue			返回值
	 *	返回:	是否读取成功
	 */
	bool IniFile::GetFloat(
		const char*	lpSection,
		const char*	lpKeyName,
		float	fDefault,
		float* pfValue)
	{
		char Buffer[32];
		if(GetKeyValue(lpSection, lpKeyName, Buffer, sizeof(Buffer)))
		{
			double value;
			value = ::atof(Buffer);
			*pfValue = (float)value;
			return true;
		}
		else
		{
			*pfValue = fDefault;
			return false;
		}
	}

	/*
	 *	功能:	读取2个浮点数，之间用逗号分割。
	 *	参数:	lpSection		节名
	 *			lpKeyName		建名
	 *			pfValue1		返回值1
	 *			pfValue2		返回值2
	 *	返回:	是否读取成功
	 */
	void IniFile::GetFloat2(
		const char* lpSection,
		const char* lpKeyName,
		float* pfValue1,
		float* pfValue2)
	{
		char  Buffer[32];
		char* pchar = Buffer;

		if(GetKeyValue(lpSection, lpKeyName, Buffer, sizeof(Buffer)))
		{
			while(*pchar)
			{
				if(',' == *pchar)
				{
					*pchar++ = 0;
					break;
				}
				pchar++;
			}

			double value;
			value = ::atof(Buffer);
			*pfValue1 = (float)value;
			value = ::atof(pchar);
			*pfValue2 = (float)value;
		}
	}

	/*
	 *	功能:	读取一个结构
	 *	参数:	lpSection		节名
	 *			lpKeyName		建名
	 *			lpStruct		缓存
	 *			dwSize			缓存大小
	 *	返回:	是否读取成功
	 */
	void IniFile::GetStruct(
		const char*	lpSection,
		const char*	lpKeyName,
		void*	lpStruct,
		unsigned long	dwSize)
	{
		char    Buffer[512];
		unsigned char*	lpByte;
		unsigned char	ah, al;

		if(!GetKeyValue(lpSection, lpKeyName, Buffer, sizeof(Buffer)))
		{		
			return;
		}

		lpByte = (unsigned char*)lpStruct;
		unsigned int len = ::strlen(Buffer);
		if(len / 2 != (unsigned int)dwSize)
		{
			return;
		}

		for(unsigned int i = 0; i < len; i += 2)
		{
			// get byte high
			ah = Buffer[i];
			if((ah >= 48) && 
				(ah <= 57))
				ah = (unsigned char)(ah - 48);
			else
				ah = (unsigned char)(ah - 65 + 10);

			// get byte low
			al = Buffer[i + 1];
			if((al >= 48) && 
				(al <= 57))
				al = (unsigned char)(al - 48);
			else
				al = (unsigned char)(al - 65 + 10);

			// set struct bye
			*lpByte++ = (unsigned char)(ah * 16 + al);
		}
	}

	/*
	 *	功能:	写入一个字符串
	 *	参数:	lpSection		节名
	 *			lpKeyName		建名
	 *			lpString		字符串
	 */
	void IniFile::WriteString(
		const char*	lpSection,
		const char*	lpKeyName,
		const char*	lpString)
	{
		SetKeyValue(lpSection, lpKeyName, lpString);
	}

	/*
	 *	功能:	写入一个整数
	 *	参数:	lpSection		节名
	 *			lpKeyName		建名
	 *			nValue			整数
	 */
	void IniFile::WriteInteger(
		const char*	lpSection,
		const char*	lpKeyName,
		int 	nValue)
	{
		char Buffer[32];

		::sprintf(Buffer, "%d", nValue);
		SetKeyValue(lpSection, lpKeyName, Buffer);
	}

	/*
	 *	功能:	写入2个整数
	 *	参数:	lpSection		节名
	 *			lpKeyName		建名
	 *			nValue1			整数1
	 *			nValue2			整数2
	 */
	void IniFile::WriteInteger2(
		const char*	lpSection,
		const char*	lpKeyName,
		int 	Value1,
		int		Value2)
	{
		char Buffer[32];

		::sprintf(Buffer, "%d,%d", Value1, Value2);
		SetKeyValue(lpSection, lpKeyName, Buffer);
	}

	/*
	 *	功能:	写入1个浮点数
	 *	参数:	lpSection		节名
	 *			lpKeyName		建名
	 *			fValue			浮点数
	 */
	void IniFile::Writefloat(
		const char*	lpSection,
		const char*	lpKeyName,
		float	fValue)
	{
		char Buffer[32];

		::sprintf(Buffer, "%f", fValue);
		SetKeyValue(lpSection, lpKeyName, Buffer);
	}

	/*
	 *	功能:	写入2个浮点数
	 *	参数:	lpSection		节名
	 *			lpKeyName		建名
	 *			fValue1			浮点数1
	 *			fValue2			浮点数2
	 */
	void IniFile::Writefloat2(
		const char*	lpSection,
		const char*	lpKeyName,
		float 	fValue1,
		float	fValue2)
	{
		char Buffer[32];

		::sprintf(Buffer, "%f,%f", fValue1, fValue2);
		SetKeyValue(lpSection, lpKeyName, Buffer);
	}

	/*
	 *	功能:	写入一个结构
	 *	参数:	lpSection		节名
	 *			lpKeyName		建名
	 *			lpStruct		结构
	 *			dwSize			结构大小
	 */
	void IniFile::WriteStruct(
		const char*	lpSection,
		const char*	lpKeyName,
		void*		lpStruct,
		unsigned long 	dwSize)
	{
		if(0 == lpSection[0] ||
			0 == lpKeyName[0] ||
			0 == dwSize ||
			!lpStruct)
			return;

		char    Buffer[512];
		char*	lpBuff = Buffer;
		unsigned char*	lpByte;

		if(dwSize * 2 >= 512)
		{
			return;
		}

		lpByte = (unsigned char*)lpStruct;
		for(unsigned long i = 0; i < dwSize; i++)
		{
			::sprintf(lpBuff, "%02x", *lpByte);
			lpBuff++;
			lpBuff++;
			lpByte++;
		}

		std::string strTemp = Buffer;
		BLK::StringUpper(strTemp);
		SetKeyValue(lpSection, lpKeyName, Buffer);
	}

	/*
	 *	功能:	写入一个布尔值
	 *	参数:	lpSection		节名
	 *			lpKeyName		建名
	 *			bbool			布尔值
	 */
	void IniFile::WriteBool(
		const char*	lpSection,
		const char*	lpKeyName,
		bool	bbool)
	{
		if(true == bbool)
			SetKeyValue(lpSection, lpKeyName, "true");
		else
			SetKeyValue(lpSection, lpKeyName, "false");
	}

	/*
	 *	功能:	得到下一个节点名
	 *	参数:	pSection		当前节点名
	 *			pNextSection	下一个节点名
	 *	返回:	是否找到下一节点
	 */
	bool IniFile::GetNextSection(
		const char* pSection, 
		char* pNextSection)
	{		
		if(!pSection[0])	//	传入参数为""时就是取第一个Section
		{
			if(!m_Header.pNextNode)
				return false;
			else
			{
				::strcpy(pNextSection, m_Header.pNextNode->pSection);
				return true;
			}
		}
		else
		{
			char szSection[32] = "[";
			if(pSection[0] != BLK_LEFT_BRACKET)
			{
				::strcat(szSection, pSection);
				::strcat(szSection, "]");
			}
			else
			{
				::strcpy(szSection, pSection);
			}

			//	查找参数给定的Section
			SECNODE* pThisSecNode = &m_Header;
			SECNODE* pNextSecNode = pThisSecNode->pNextNode;
			unsigned long dwID = String2Id(szSection);
			while(pNextSecNode != NULL)
			{
				if(dwID == pNextSecNode->dwID)
				{
					break;
				}
				pThisSecNode = pNextSecNode;
				pNextSecNode = pThisSecNode->pNextNode;
			}

			//	没有这个Section，无所谓下一个
			if(!pNextSecNode)
			{
				return false;
			}
			else
			{
				//	参数给定的Section已经是最后一个了
				if(!pNextSecNode->pNextNode)
				{
					return false;
				}
				else	
				{
					::strcpy(pNextSection, pNextSecNode->pNextNode->pSection);
					return true;
				}
			}
		}
	}

	/*
	 *	功能:	得到下一个键值
	 *	参数:	pSection	节点名
	 *			pKey		当前键
	 *			pNextKey	下一个键
	 *	返回:	是否找到下一个键
	 */
	bool IniFile::GetNextKey(
		const char* pSection, 
		const char* pKey, 
		char* pNextKey)
	{
		char szSection[32] = "[";
		if(pSection[0] != BLK_LEFT_BRACKET)
		{
			::strcat(szSection, pSection);
			::strcat(szSection, "]");
		}
		else
		{
			::strcpy(szSection, pSection);
		}

		//	查找参数给定的Section
		SECNODE* pThisSecNode = &m_Header;
		SECNODE* pNextSecNode = pThisSecNode->pNextNode;
		unsigned long dwID = String2Id(szSection);
		while(pNextSecNode != NULL)
		{
			if(dwID == pNextSecNode->dwID)
			{
				break;
			}
			pThisSecNode = pNextSecNode;
			pNextSecNode = pThisSecNode->pNextNode;
		}

		//	没有这个Section，无所谓取Key
		if(!pNextSecNode)
		{
			return false;
		}

		KEYNODE* pThisKeyNode = &pNextSecNode->pKeyNode;
		KEYNODE* pNextKeyNode = pThisKeyNode->pNextNode;

		//	Key给的参数为""的话，取第一个Key
		if(!pKey[0])
		{
			//	没有Key，返回失败
			if(!pNextKeyNode->pKey)
			{
				return false;
			}
			else
			{
				::strcpy(pNextKey, pNextKeyNode->pKey);
				return true;
			}
		}

		dwID = String2Id(pKey);
		while(pNextKeyNode != NULL)
		{
			if(dwID == pNextKeyNode->dwID)
			{
				break;
			}
			pThisKeyNode = pNextKeyNode;
			pNextKeyNode = pThisKeyNode->pNextNode;
		}

		//	找不到所给的Key，无所谓下一个
		if(!pNextKeyNode)
		{
			return false;
		}

		//	参数给定的Key已经是最后一个了
		if(!pNextKeyNode->pNextNode)
		{
			return false;
		}
		else
		{
			::strcpy(pNextKey, pNextKeyNode->pNextNode->pKey);
			return true;
		}
	}

	/*
	 *	功能:	得到节点的数量
	 *	返回:	节点的数量
	 */
	int	IniFile::GetSectionCount(void)
	{
		char Section[200];
		char Section1[200];

		if(!GetNextSection(BLK_EMPTY_STR, Section)) 
			return 0;

		int i = 1;
		while(1)
		{
			::strcpy(Section1, Section);
			if(!GetNextSection(Section1, Section)) 
				return i;
			i++;
		}
		return i;
	}

	/*
	 *	功能:	读取一个矩形
	 *	参数:	lpSection		节名
	 *			lpKeyName		建名
	 *			pRect			读取矩形
	 */ 
	void IniFile::GetRect(
		const char* lpSection, 
		const char* lpKeyName, 
		RECT* pRect)
	{
		char  Buffer[256];

		if(GetKeyValue(lpSection, lpKeyName, Buffer, sizeof(Buffer)))
		{
			const char* pcszTemp = Buffer;
	        
			pRect->left   = BLK::StringGetInt(&pcszTemp, 0);
			BLK::StringSkipSymbol(&pcszTemp, ',');
			pRect->top    = BLK::StringGetInt(&pcszTemp, 0);
			BLK::StringSkipSymbol(&pcszTemp, ',');
			pRect->right  = BLK::StringGetInt(&pcszTemp, 0);
			BLK::StringSkipSymbol(&pcszTemp, ',');
			pRect->bottom = BLK::StringGetInt(&pcszTemp, 0);
		}
	}

	/*
	 *	功能:	读取3个浮点数，之间用逗号分割。
	 *	参数:	lpSection		节名
	 *			lpKeyName		建名
	 *			pfloat			读取浮点数指针
	 */
	void IniFile::GetFloat3(
		const char* lpSection,
		const char* lpKeyName, 
		float* pfloat)
	{
		char	Buffer[256];

		if(GetKeyValue(lpSection, lpKeyName, Buffer, sizeof(Buffer)))
		{
			// sscanf还没封到平台库里，先如此调用 lucien
			sscanf(Buffer, "%f,%f,%f", &pfloat[0], &pfloat[1], &pfloat[2]);
		}
	}

	/*
	 *	功能:	读取4个浮点数，之间用逗号分割。
	 *	参数:	lpSection		节名
	 *			lpKeyName		建名
	 *			pfloat			读取浮点数指针
	 */
	void IniFile::GetFloat4(
		const char* lpSection, 
		const char* lpKeyName, 
		float* pfloat)
	{
		char  Buffer[256];

		if(GetKeyValue(lpSection, lpKeyName, Buffer, sizeof(Buffer)))
		{
			// sscanf还没封到平台库里，先如此调用 lucien
			sscanf(Buffer, "%f,%f,%f,%f", &pfloat[0], &pfloat[1], &pfloat[2], &pfloat[3]);
		}
	}

	/*
	 *	功能:	读取一个布尔值
	 *	参数:	lpSection		节名
	 *			lpKeyName		建名
	 *			pbool			读取布尔值
	 */
	void IniFile::GetBool(
		const char* lpSection,
		const char* lpKeyName, 
		bool* pbool)
	{
		char  Buffer;

		if(GetKeyValue(lpSection, lpKeyName, &Buffer, 1))
		{
			if('T' == Buffer || 't' == Buffer)
				*pbool = true;
			else
				*pbool = false;
		}
	}

};	// Namespace End
